import configparser
import json
import os
from uuid import uuid4

from django.conf import settings
from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage
from django.http import JsonResponse
from django.utils import timezone
from django.views import View
from scripts.models import Script, ScriptRunningHistory, ScriptRunningHosts

from common.response import Reponse

from .ansibleapi import AnsibleObj
from .forms import HostForm
from .inventory import JsonInventory

scripts_fs = FileSystemStorage(location=settings.SCRIPT_ROOT_DIR)
fs = FileSystemStorage("/tmp/tmp_inventory")

# 命令执行


class CommandRunView(View):
    def post(self, request):
        request_data = json.loads(request.body)
        print(request_data)
        os.path.join(settings.BASE_DIR, 'playbooks/command.yaml')
        resp = Reponse()
        resp.msg = "ok"
        return resp.json_response()


class RunnerView(View):
    def post(self, request, run_type):
        request_data = json.loads(request.body)
        result = {
            'success': '',
            'failed': '',
            'unreachable': '',
            'invalid': ''
        }
        # 获取执行类型
        request_data['type'] = run_type
        # 排除重复的主机信息
        hosts = list(tuple(request_data.get('hosts')))
        # 验证传入的主机信息合法性
        hosts = HostForm.valid(hosts)

        # 创建hosts文件
        try:
            inventory = create_inventory(hosts.get('valid'))
        except Exception as e:
            raise e
        ar = AnsibleObj(inventory=inventory)
        # 命令控制台
        if "command" == run_type:
            try:
                ar.run_command(request_data.get(
                    'cmd', 'echo please type a command'))
            except Exception as e:
                raise e
            result = ar.get_result()

        # 脚本控制台
        if "script" == run_type:
            try:
                script = Script.objects.get(pk=request_data.get('script_id'))
                history = ScriptRunningHistory(script_id=script.pk)
                history.save()
                host_history = {}
                for host in hosts.get('valid'):
                    host_history[host.get('ansible_ssh_host')] = ScriptRunningHosts(
                        script_running_history_id=history.pk, host_name=host.get('ansible_ssh_host'))
                    host_history[host.get('ansible_ssh_host')].save()
            except Exception as e:
                raise e
            if 'Playbook' == script.script_type:
                script_path = scripts_fs.path(
                    str(script.script_path+'main.yml'))
                try:
                    ar.run_playbook([script_path])
                except Exception as e:
                    raise e
            else:
                try:
                    script_path = scripts_fs.path(
                        str(script.script_path+str(script.script_id)))
                    ar.run_script(script_path)
                except Exception as e:
                    raise e
            # 获取ansible执行结果
            result = ar.get_result()

            try:
                for k, v in result.get('last_stats').items():
                    host_history[k].ip = v.get('host_ip')
                    host_history[k].status = v.get('stats')
                    host_history[k].result = v.get('result_info').get(
                        'msg', v.get('result_info').get('stdout'))
                    host_history[k].exit_code = v.get('result_info').get('rc')
                    host_history[k].save()
            except Exception as e:
                raise e
            # 返回结果添加非法主机列表
            result.update({'invalid': hosts.get('invalid')})

            history.end_at = timezone.now()
            history.save()

        return JsonResponse({'result': result})


def create_inventory(valid_hosts: list):
    content = ""
    for host in valid_hosts:
        line = host.get('ansible_ssh_host')+" "
        for k, v in host.items():
            if v:
                line = line+k+"="+v+" "
        content = content+line+"\n"
    f = ContentFile(content)
    f_name = fs.save(name=str(uuid4()), content=f)

    return fs.path(f_name)
